function varargout = TLMultiPortSwitchDlg(action,varargin)

% TL_MULTIPORTSWITCH_DLG manages the user interface for TargetLink Multiport Switch block
%
% SYNTAX dlgInfo = TLMultiportswitchDlg('GetDlgInfo');
%   gets dialog info of TargetLink Multiport Switch block
%
%   INPUT ARGUMENTS
%   -/-      
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = TLMultiportswitchDlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = TLMultiportswitchDlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = TLMultiportswitchDlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = TLMultiportswitchDlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX TLMultiportswitchDlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit, T. Pietzsch
% $RCSfile: TLMultiportswitchDlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/CommonBlockset/CommonBlockset_SimBlocksUI/Sources/MSrc/project.pj $
% $Revision: 1.15 $
% $Date: 2011/04/06 08:58:37MESZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action
    
    case 'GetDlgInfo'
        hBlock = varargin{1};
        dlgInfo = tl_get_dlginfodefaults('tlsim');
        titleName = 'Multiport Switch';
        pathinfo = tl_pathinfo(hBlock);
        dlgInfo.title = sprintf('TargetLink %s: %s', titleName, pathinfo.shortDisplayName);
        dlgInfo.pageNames   = {
            'Output'; ...
            'Logging & Autoscaling'; ...
            'Documentation'};
        varargout{1} = dlgInfo;
        varargout{2} = get_tlcg_data(hBlock);
        
    case 'CtrlPositions'
        pageName     = varargin{1};
        commonGeom   = varargin{2};
        sheetDims    = varargin{4};
        switch pageName
            case 'Output'
                [sheetDims, ctrlPos] = FcnOutputCtrlPositions(commonGeom);
                
            case 'Logging & Autoscaling'
                excludedCtrls = {'keepParameter'};
                [sheetDims, ctrlPos] = ...
                    TLManageLoggingCtrls('calcCtrls', commonGeom, sheetDims, excludedCtrls);
                
            case 'Documentation'
                bTblBlock = 0;
                bCodeComment = 1;
                [sheetDims,ctrlPos] = ...
                    TLManageDocCtrls('ctrlpos', commonGeom, sheetDims, bCodeComment, bTblBlock);
        end
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;
        
    case 'Create'
        pageName = varargin{1};
        dlgfig   = varargin{2};
        dlgdata  = varargin{3};
        pageNum  = find(strcmp(pageName, dlgdata.pageNames));
        switch pageName
            case 'Output'
                dlgdata = ...
                    FcnCreateOutputPage(pageNum,dlgfig,dlgdata);
                
            case 'Logging & Autoscaling'
                % set bCheckLogging, because block supports bus signals
                dlgdata.pageData{pageNum}.bCheckLogging = 1;
                dlgdata = ...
                    TLManageLoggingCtrls('create',pageNum,dlgfig,dlgdata);
                
            case 'Documentation'
                dlgdata = ...
                    TLManageDocCtrls('create',pageNum,dlgfig,dlgdata);
        end
        dlgdata.pageData{pageNum}.ctrlPos = [];
        varargout{1} = dlgdata;
        
    case 'Manage',
        pageName   = varargin{1};
        dlgfig     = varargin{2};
        dlgdata    = varargin{3};
        pageAction = varargin{4};
        pageNum    = find(strcmp(pageName, dlgdata.pageNames));
        
        switch pageName
            case 'Output'
                [dlgdata,bModified] = ...
                    FcnManageOutputPage(pageNum, dlgfig, dlgdata, pageAction);
                
            case 'Logging & Autoscaling'
                [dlgdata, bModified] = ...
                    TLManageLoggingCtrls('manage', pageNum, dlgdata, pageAction, 'logdata');
                
            case 'Documentation'
                [dlgdata,bModified] = ...
                    TLManageDocCtrls('callback', pageNum, dlgfig, dlgdata, pageAction);
        end
        varargout{1} = dlgdata;
        varargout{2} = bModified;
        
    case 'ManageSystemIcons',
        dlgfig     = varargin{1};
        dlgdata    = varargin{2};
        pageAction = varargin{3};
        [dlgdata, bModified] = FcnManageSystemIcons(dlgfig,dlgdata,pageAction);
        varargout{1} = dlgdata;
        varargout{2} = bModified;
        
    case 'Update'
        dlgfig  = varargin{1};
        dlgdata = varargin{2};
        pageNum = varargin{3};
        
        pageName  = dlgdata.pageNames{pageNum};
        switch pageName
            case 'Output'
                dlgdata = FcnUpdateOutputPage(dlgdata, dlgfig, pageNum);
                
            case 'Logging & Autoscaling'
                dlgdata =  TLManageLoggingCtrls('update',pageNum,dlgdata,'logdata','output');
                TLManageLoggingCtrls('setCtrls',pageNum, dlgfig, dlgdata);
                
            case 'Documentation'
                TLManageDocCtrls('update', pageNum, dlgfig, dlgdata);
        end
        varargout{1} = dlgdata;
        
    case 'Apply'
        dlgdata  = varargin{2};
        bClose   = varargin{3};
        [dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);
        varargout{1} = dlgdata;
        varargout{2} = bClose;
        
    otherwise
        error(['Invalid action "' action '"']);
end


%-----------------------------------------------------------------------------------------
% FcnManageSystemIcons manage actions of toolbar icons
%
% INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageSystemIcons(dlgfig, dlgdata, action) %#ok

bModified = false;
switch action
    case 'EditCode'
        % look for associated production code file
        [codefile,blockstr] = get_codefile(dlgdata.model);
        if ~isempty(codefile)
            codeedit(codefile,blockstr);
        end
        
    case 'ViewCode'
        tl_create_links_to_model('ShowComputation',dlgdata.model, 'output');
        
    otherwise
        error('Invalid callback');
        
end % switch(action)


%-----------------------------------------------------------------------------------------
% FcnOutputCtrlPositions calculates positions for all controls on output page
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims, ctrlPos] = FcnOutputCtrlPositions(commonGeom)

excludedCtrls = { };
[sheetDims, ctrlPos, col, colDelta, rowDelta] = ...
    tl_calc_ctrls_positions(commonGeom, excludedCtrls);

strings_and_styles = {
    'Number of inputs:',   'text';
    'Zero-based indexing',      'checkbox';
    'Data port for default case:',   'text';
    'Number of data ports:',   'text';
    repmat('m',1,18), 'popupmenu';
    };

[ninpLabelSize, zeroIdxCheckboxSize, ...
    dataPortDefaultLabelSize, ...
    dataPortLabelSize, dataPortPopupSize] = ...
    ds_get_uicontrol_sizes(commonGeom, strings_and_styles);

%-----------------------------------------------------------
% all controls lie in one row until R2010a
%-----------------------------------------------------------
cy = commonGeom.frameBottomEdgeBuffer;
cx = col(1);

vs = get_param(0,'version');
if vs >= 7.6     % >= R2010b
    % data port default popup
    ctrlPos.defaultDataPortPopup = [cx cy dataPortPopupSize];
    
    % data port default label
    cy = cy + commonGeom.editHeight;
    cx = col(1);
    ctrlPos.defaultDataPortLabel = [cx cy (dataPortDefaultLabelSize)];
    
    ctrlPos.addoptGroupbox(4) = ctrlPos.addoptGroupbox(4) ...
        + rowDelta + 2 * commonGeom.editHeight;
    cy = cy + commonGeom.editHeight + rowDelta;
end

if vs >= 7.5     % >= R2010a
    % data port order popup
    cx = col(1);
    ctrlPos.dataPortOrderPopup = [cx cy dataPortPopupSize];
    
    % number of input edit field
    cx = col(3);
    ctrlPos.ninpEdit = [cx cy ctrlPos.widthEdit(3:4)];
    % ctrlPos.ninpEdit = [cx cy dataPortPopupSize .* [0.5 1]];
    
    % number of input counter controls
    cx = sum(ctrlPos.ninpEdit([1 3])) + 5;
    ctrlPos.ninpupButton =  ...
        [cx (cy + commonGeom.editHeight / 2) ctrlPos.widthDownButton(3:4)];
    ctrlPos.ninpdownButton = ...
        [cx cy ctrlPos.widthDownButton(3:4)];
    
    % data port indices edit
    cx = col(5);
    dx = ctrlPos.descEdit(1) + ctrlPos.descEdit(3) - col(5);
    ctrlPos.dataPortIndicesEdit = [cx cy dx dataPortPopupSize(2)];
    
    cy = cy + commonGeom.editHeight;
    cx = col(1);
    % data port order label
    ctrlPos.dataPortOrderLabel = [cx cy dataPortLabelSize];
    
    % number of inputs label
    cx = col(3);
    ctrlPos.ninpLabel = [cx cy dataPortLabelSize];
    
    % data port indices label
    cx = col(5);
    ctrlPos.dataPortIndicesLabel = [cx cy dataPortLabelSize];
    
    ctrlPos.addoptGroupbox(4) = ctrlPos.addoptGroupbox(4) ...
        + commonGeom.textHeight;
else
    % number of inputs label
    ctrlPos.ninpLabel = [cx cy ninpLabelSize];
    
    % number of input edit field
    cx = cx + ninpLabelSize(1) + colDelta / 3;
    ctrlPos.ninpEdit = [cx cy ctrlPos.widthEdit(3:4)];
    
    % number of input counter controls
    cx = sum(ctrlPos.ninpEdit([1 3])) + 5;
    ctrlPos.ninpupButton =  ...
        [cx (cy + commonGeom.editHeight / 2) ctrlPos.widthDownButton(3:4)];
    ctrlPos.ninpdownButton = ...
        [cx cy ctrlPos.widthDownButton(3:4)];
    
    % zero-based indexing checkbox
    cx = col(3);
    ctrlPos.zeroIdxCheckbox = [cx, cy, zeroIdxCheckboxSize];
end

% increase sheet dimensions
sheetDims(2) = sheetDims(2) ...
    + ctrlPos.addoptGroupbox(4) ...
    + commonGeom.editHeight;


%-----------------------------------------------------------------------------------------
% FcnCreateSwitchPointsControls creates the figure window
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateOutputPage(pageNum,dlgfig,dlgdata)

% create all controls
dlgdata = TLManageVariableCtrls('create', pageNum, dlgfig, dlgdata);
dlgdata = TLManageScalingCtrls('create', pageNum, dlgfig, dlgdata, 'output');

ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;
Children = dlgdata.pageData{pageNum}.children;
pageName = dlgdata.pageNames{pageNum};
vs = get_param(0,'version');
if vs < 7.5 % < 2010a
    addoptGroupboxText = ' Number of inputs ';
    ninpLabelText = 'Number of inputs:';
else
    addoptGroupboxText = ' Data ports ';
    ninpLabelText = 'Number of data ports:';
end
% create the addoptGroupbox which will contain further options
Children.addoptGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {addoptGroupboxText}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.addoptGroupbox);

% create first data port order control for intuitive keyboard navigation
if vs >= 7.5 % >= 2010a
    Children.dataPortOrderLabel = uicontrol( ...
        'Parent',             Children.addoptGroupbox, ...
        'String',             'Data port order:', ...
        'Style',              'text', ...
        'Position',           ctrlPos.dataPortOrderLabel);
    Children.dataPortOrderPopup = uicontrol( ...
        'Parent',             Children.addoptGroupbox, ...
        'BackGroundColor',   'w', ...
        'Style',              'popupmenu', ...
        'Position',           ctrlPos.dataPortOrderPopup, ...
        'Callback',           sprintf('tldlg(''%s'',gcbf,''dataPortOrderPopup'')',pageName));
end

% number of inputs controls
Children.ninpLabel = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'text', ...
    'String',             ninpLabelText, ...
    'Position',           ctrlPos.ninpLabel);

userData = struct('min', 1, 'max', 2^31-1);
Children.ninpEdit = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'BackgroundColor',    'w', ...
    'Style',              'edit', ...
    'Position',           ctrlPos.ninpEdit, ...
    'UserData',           userData, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''ninpEdit'')',pageName));

Children.ninpupButton = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'pushbutton', ...
    'String',             '+', ...
    'Position',           ctrlPos.ninpupButton, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''ninpupButton'')',pageName));

Children.ninpdownButton = uicontrol( ...
    'Parent',             Children.addoptGroupbox, ...
    'Style',              'pushbutton', ...
    'String',             '-', ...
    'Position',           ctrlPos.ninpdownButton, ...
    'Callback',           sprintf('tldlg(''%s'',gcbf,''ninpdownButton'')',pageName));

% zero-based indexing checkbox
if vs < 7.5 % < 2010a
    Children.zeroIdxCheckbox = uicontrol( ...
        'Parent',             Children.addoptGroupbox, ...
        'Style',              'checkbox', ...
        'String',             'Zero-based indexing', ...
        'Position',           ctrlPos.zeroIdxCheckbox, ...
        'Callback',           sprintf('tldlg(''%s'',gcbf,''zeroIdxCheckbox'')',pageName));
else
    Children.dataPortIndicesLabel = uicontrol( ...
        'Parent',             Children.addoptGroupbox, ...
        'String',             'Data port indices:', ...
        'Style',              'text', ...
        'Position',           ctrlPos.dataPortIndicesLabel);
    
    Children.dataPortIndicesEdit = uicontrol( ...
        'Parent',             Children.addoptGroupbox, ...
        'Style',              'edit', ...
        'Position',           ctrlPos.dataPortIndicesEdit, ...
        'Callback',           sprintf('tldlg(''%s'',gcbf,''dataPortIndicesEdit'')',pageName));
    
    if vs >= 7.6 % >= 2010b
        Children.defaultDataPortLabel = uicontrol( ...
            'Parent',             Children.addoptGroupbox, ...
            'String',             'Data port for default case:', ...
            'Style',              'text', ...
            'Position',           ctrlPos.defaultDataPortLabel);
        
        Children.defaultDataPortPopup = uicontrol( ...
            'Parent',             Children.addoptGroupbox, ...
            'BackGroundColor',   'w', ...
            'Style',              'popupmenu', ...
            'Position',           ctrlPos.defaultDataPortPopup, ...
            'Callback',           sprintf('tldlg(''%s'',gcbf,''defaultDataPortPopup'')',pageName));
    end
end
dlgdata.pageData{pageNum}.children = Children;


%-----------------------------------------------------------------------------------------
% FcnManageOutputPage manage control actions of output page
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageOutputPage(pageNum,dlgfig,dlgdata,action)

Children = dlgdata.pageData{pageNum}.children;
switch action
    case {'ninpEdit', 'ninpupButton', 'ninpdownButton'}
        [inputs, bModified] = ...
            tl_handle_editupdown('Manage', dlgdata.data.inputs, ...
            [Children.ninpEdit Children.ninpupButton Children.ninpdownButton], ...
            Children.(action));
        if bModified
            dlgdata.data.inputs = inputs;
        end
    case 'dataPortIndicesEdit'
        str = tl_deblank(get(Children.dataPortIndicesEdit,'String'),2);
        if numel(str) == 0
            beep;
        else
            dlgdata.data.dataportindices = str;
            bModified = 1;
        end
        
    case 'zeroIdxCheckbox'
        dlgdata.data.zeroidx = get(Children.zeroIdxCheckbox, 'Value');
        bModified = 1;
        
    case 'dataPortOrderPopup'
        dlgdata.data.dataportorder = get(Children.dataPortOrderPopup, 'Value');
        bModified = 1;
        
    case 'defaultDataPortPopup'
        dlgdata.data.dataportfordefault = get(Children.defaultDataPortPopup, 'Value');
        bModified = 1;
        
    otherwise
        [dlgdata,bModified1] = ...
            TLManageVariableCtrls('manage', pageNum, dlgfig, dlgdata, action, 'output');
        [dlgdata,bModified2] = ...
            TLManageScalingCtrls('manage', pageNum, dlgfig, dlgdata, action, 'output');
        bModified = bModified1 | bModified2;
end


%--------------------------------------------------------------------------
% FcnUpdateOutputPage updates the output controls
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateOutputPage(dlgdata,dlgfig,pageNum)

enums = tl_manage_blockset('GetEnums');
dataPortOrderEnum   = enums(strcmp({enums.name},'DataPortOrderEnum'));
defaultDataPortEnum = enums(strcmp({enums.name},'DefaultDataPortEnum'));

statusLabelUserData = get(dlgdata.SystemButtons.StatusLabel,'UserData');

Children = dlgdata.pageData{pageNum}.children;
vs = get_param(0,'version');

% update all variable controls
dlgdata = TLManageVariableCtrls('update', pageNum, dlgdata, 'output');
dlgdata = TLManageScalingCtrls('update', pageNum, dlgdata, 'output', []);

% get new states for bit index - edit, buttonUp and buttonDown
value = dlgdata.data.inputs;
states = tl_handle_editupdown('update', value, dlgdata, pageNum, 'ninpEdit');

if  vs >= 7.5 && dlgdata.data.dataportorder == 3
    states.edit = 'off';
    states.up   = 'off';
    states.down = 'off';
    states.label = 'off';
else
    states.label = 'on';
end

% bit index edit
userData = get(Children.ninpEdit, 'UserData');
userData.ctrlStatus = struct('enable', states.edit, 'string', dlgdata.data.inputs);
if ~states.isValid
    % wrong input (maybe inserted outside the dialog) -> color text red
    userData.ctrlStatus.iserror = true;
end
set(Children.ninpEdit, 'UserData', userData);
% up button
userData = get(Children.ninpupButton, 'UserData');
userData.ctrlStatus = struct('enable', states.up);
set(Children.ninpupButton, 'UserData', userData);
% down button
userData = get(Children.ninpdownButton, 'UserData');
userData.ctrlStatus = struct('enable', states.down);
set(Children.ninpdownButton, 'UserData', userData);
% label
userData = get(Children.ninpLabel,'UserData');
userData.ctrlStatus = struct('enable', states.label);
set(Children.ninpLabel, 'UserData', userData);

ctrlsList = { ...
    'ninpEdit', ...
    'ninpupButton', ...
    'ninpdownButton', ...
    'ninpLabel'};

statusLabelUserData.ctrlStatus.string = '';
if vs < 7.5 % < 2010a
    % Zero-based indexing
    userData = get(Children.zeroIdxCheckbox, 'UserData');
    userData.ctrlStatus = struct('enable', 'on', 'value', dlgdata.data.zeroidx);
    set(Children.zeroIdxCheckbox, 'UserData', userData);
    ctrlsList{end+1} = 'zeroIdxCheckbox';
else
    userData = get(Children.dataPortOrderPopup, 'UserData');
    userData.ctrlStatus = struct('enable', 'on');
    userData.ctrlStatus.string = dataPortOrderEnum.strings;
    userData.ctrlStatus.value  = dlgdata.data.dataportorder;
    set(Children.dataPortOrderPopup, 'UserData', userData);
    ctrlsList{end+1} = 'dataPortOrderPopup';
    
    userData = get(Children.dataPortIndicesEdit, 'UserData');
    if dlgdata.data.dataportorder == 3
        userData.ctrlStatus = struct('enable','on','BackGroundColor','w','string',dlgdata.data.dataportindices);
        [indices,bResolved] = tl_resolve(dlgdata.data.dataportindices,dlgdata.model);
        if bResolved
            statusLabelUserData.ctrlStatus.string = FcnCheckIndices(indices);
            if ~isempty(statusLabelUserData.ctrlStatus.string)
                userData.ctrlStatus.iserror = 1;
            end
        end
    else
        hdlgfig = get(dlgfig,'Parent');
        userData.ctrlStatus = struct('enable','off','BackGroundColor',get(hdlgfig,'Color'),'string','');
    end
    
    set(Children.dataPortIndicesEdit, 'UserData', userData);
    ctrlsList{end+1} = 'dataPortIndicesEdit';
    
    if vs >= 7.6  % >= 2010b
        userData = get(Children.defaultDataPortPopup, 'UserData');
        numInputs = eval(dlgdata.data.inputs);
        if numInputs > 1 || dlgdata.data.dataportorder == 3
            userData.ctrlStatus = struct('enable', 'on');
            userData.ctrlStatus.string = defaultDataPortEnum.strings;
            userData.ctrlStatus.value  = dlgdata.data.dataportfordefault;
        else
            userData.ctrlStatus = struct('enable', 'off', 'value', 1, 'string',defaultDataPortEnum.strings{1});
        end
        set(Children.defaultDataPortPopup, 'UserData', userData);
        ctrlsList{end+1} = 'defaultDataPortPopup';
    end
end
set(dlgdata.SystemButtons.StatusLabel,'UserData',statusLabelUserData);

% set controls
TLManageVariableCtrls('setCtrls',pageNum,dlgfig,dlgdata);
TLManageScalingCtrls('setCtrls',pageNum,dlgfig,dlgdata);
TLSetCtrlsStatus(dlgfig,Children, ctrlsList);

%--------------------------------------------------------------------------
% FcnCheckIndices checks cell array with indices
%
% INPUT ARGUMENTS
%   indices     dataportindices property
%
% OUTPUT ARGUMENTS
%   errStr    empty string on success, an error message otherwise
%--------------------------------------------------------------------------
function errStr = FcnCheckIndices(indices)

errStr = '';
allIndices = [];
if isempty(indices) || ~iscell(indices)
    errStr = 'Data inconsistent: data port indices must evaluate to a cell array.';
    return;
end
if numel(indices) == 1
    errStr = 'Data inconsistent: data port indices must evaluate to a cell array with > 1 elements.';
end
for i=1:numel(indices)
    if ~isa(indices{i},'double')
        errStr = 'Data inconsistent: TargetLink supports only numeric (non-enum) indices.';
        return;
    else
        if ~all(round(indices{i}) == indices{i})
            errStr = 'Data inconsistent: indices must be integers.';
            return;
        end
        if ~isreal(indices{i})
            errStr = 'Data inconsistent: indices must be real.';
            return;
        end
        allIndices = FcnCat(allIndices,indices{i});
    end
end
if numel(allIndices) ~= numel(unique(allIndices))
    errStr = 'Data inconsistent: each index may only be used once.';
end

%================================================================================
% Function concatenates structs to a row vector.
% Input parameters
%   s1      1st struct
%   s2      2nd struct
%
% Output parameters
%   s       struct row vector containing s1 and s2
%================================================================================
function s = FcnCat(s1,s2)

if all(size(s1) > 1)
    s1 = s1(:)';
end
if all(size(s2) > 1)
    s2 = s2(:)';
end

% if any struct is a column vector, transpose it
if size(s1,1) ~= 1
    s1 = s1';
end
if size(s2,1) ~= 1
    s2 = s2';
end
s = [s1 s2];
